﻿<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>文件管理器</title>
    <script src="jquery.js"></script>

    <style type="text/css">
        span {
            cursor: pointer;
            color: blue;
        }
    </style>

    <script type="text/javascript">

        let apiConstants = {
            API_STATUS_SUCCES: 1,//成功
            API_STATUS_FAIL: 2,//失败
            API_STATUS_EXCEPTION: 3,//异常
            API_STATUS_AUTH_FAIL: 4,//认证失败
            AJAX_REQ_ERROR: 5,//ajax请求错误
        };

        //获取当前本地时间的时间戳
        function getTimestamp() {
            let dateTime = new Date();
            return dateTime.getTime() - dateTime.getTimezoneOffset() * 60 * 1000;
        }






        let baseUrl = window.document.location.origin + "/api/v1/fileService/";
        let _path = "";
        let tbListEle = null;
        let tbUploadEle = null;
        let dataList = null;
        let filterText = "";
        let lastPath = null;

        function showErr(err) {
            alert(err);
        }

        function showErrRet(err, p1) {
            if (err.status == 200) {
                //浏览器bug,内容复杂的json解析会失败,提示说解析错误.不鸟它
                showErr("浏览器内容复杂的json解析会失败");
            }
            else {
                showErr(err.statusText);
            }
        }

        function toShowyyyyMMddHHmmss(date) {
            if (!(date instanceof Date)) {
                throw "date,且不能为空或未定义";
            }

            let year = date.getFullYear();
            let month = date.getMonth() + 1;//月取值0-11，所以+1
            let days = date.getDate();
            let h = date.getHours();
            let m = date.getMinutes();
            let s = date.getSeconds();
            return year + "-" + month + "-" + days + " " + h + ":" + m + ":" + s;
        }


        function refreshNav() {
            let arr = _path.split('/')
            let tmpPath = "";
            let html = "";
            for (let i = 0; i < arr.length; i++) {
                if (i == 0) {
                    html += '<span data-path="" onclick="chioceDir(this)">..</span>';
                }
                else {
                    tmpPath += "/" + arr[i];
                    html += '/<span data-path="' + tmpPath + '" onclick="chioceDir(this)">' + decodeURIComponent(arr[i]) + '</span>';
                }
            }

            let divNavEle = document.getElementById("divNav");
            divNavEle.innerHTML = html;
        }

        function showList() {
            let html = '<thead>\
                            <tr>\
                                <td style="width:50px">选中</td>\
                                <td style="width:500px">名称</td>\
                                <td style="width:200px">创建时间</td>\
                                <td style="width:200px">最后修改时间</td>\
                                <td style="width:200px">文件长度(K)/文件数</td>\
                            </tr>\
                        </thead> ';

            let dir = null;
            for (let item of dataList) {

                if (filterText == null || filterText == undefined || filterText == "") {

                }
                else {
                    if (!item.name.toLowerCase().includes(filterText)) {
                        continue;
                    }
                }

                if (item.length > 0) {
                    if (dir == null) {
                        let arr = _path.split('/');
                        let flag = true;
                        for (let d of arr) {
                            if (d == '') {
                                continue;
                            }

                            if (flag) {
                                flag = false;
                            }
                            else {
                                if (dir == null) {
                                    dir = d;
                                }
                                else {
                                    dir += '/';
                                    dir += d;
                                }
                            }
                        }

                        if (dir == null) {
                            dir = '';
                        }
                    }


                    html += '<tr data-type="1">\
                                <td><input type="checkbox" /></td >\
                                <td><a href="'+ dir + '/' + encodeURIComponent(item.url) + '" download>' + item.name + '</a></td>\
                                <td>'+ item.createTime + '</td>\
                                <td>'+ item.lastModifyTime + '</td>\
                                <td>'+ item.length / 1000 + '</td>\
                            </tr>';
                }
                else {
                    html += '<tr data-type="0">\
                                <td><input type="checkbox" /></td >\
                                <td> <span onclick="switchDir(\''+ encodeURIComponent(item.url) + '\')">' + item.name + '</span></td>\
                                <td>'+ item.createTime + '</td>\
                                <td>'+ item.lastModifyTime + '</td>\
                                <td>目录('+ item.count + ')</td>\
                            </tr>';
                }
            }

            tbList.innerHTML = html;
        }

        function refreshList(path) {
            let url;
            if (path != null) {
                url = baseUrl + "getFileSystemInfos?path=" + path;
                lastPath = path;
            }
            else {
                url = baseUrl + "getFileSystemInfos?path=";
                lastPath = null;
            }

            $.ajax({
                type: "GET",
                url: url,
                async: true,
                contentType: "application/json; charset=utf-8",
                //dataType: "json",
                success: function (ret, status, p1) {
                    if (ret.status == apiConstants.API_STATUS_SUCCES) {
                        dataList = JSON.parse(ret.data);
                        showList();
                        refreshNav();
                    }
                    else {
                        showErr(ret.data);
                    }
                },
                error: showErrRet
            });
        }

        function deepSearch() {
            let searchKey = document.getElementById("txtSearchKey").value.trim();
            let url;
            if (searchKey == null || searchKey == undefined || searchKey === "") {
                //当搜索关键字为空时,显示最后的目录内容
                if (lastPath != null) {
                    url = baseUrl + "getFileSystemInfos?path=" + lastPath;
                }
                else {
                    url = baseUrl + "getFileSystemInfos?path=";
                }
            }
            else {
                if (lastPath != null) {
                    url = baseUrl + "searchFileSystemInfos?searchKey=" + searchKey + "&path=" + lastPath;
                }
                else {
                    url = baseUrl + "searchFileSystemInfos?searchKey=" + searchKey + "&path=";
                }
            }

            $.ajax({
                type: "GET",
                url: url,
                async: true,
                contentType: "application/json; charset=utf-8",
                //dataType: "json",
                success: function (ret, status, p1) {
                    if (ret.status == apiConstants.API_STATUS_SUCCES) {
                        dataList = JSON.parse(ret.data);
                        showList();
                        refreshNav();
                    }
                    else {
                        showErr(ret.data);
                    }
                },
                error: showErrRet
            });
        }







        function checkAll() {
            let trEles = tbList.children[1].children;
            for (let trEle of trEles) {
                trEle.children[0].children[0].checked = true;
            }
        }

        function unCheckAll() {
            let trEles = tbList.children[1].children;
            for (let trEle of trEles) {
                trEle.children[0].children[0].checked = false;
            }
        }

        function unCheck() {
            let trEles = tbList.children[1].children;
            for (let trEle of trEles) {
                trEle.children[0].children[0].checked = !trEle.children[0].children[0].checked;
            }
        }

        function onRefresh() {
            refreshList(_path);
        }


        //http-post 上传文件
        let uploadProBar = null;
        let _uploadFileList = [];
        let _uploading = false;
        let _uploadRow = null;

        function primitiveUploadFile() {
            if (_uploadFileList.length == 0) {
                _uploading = false;
                _uploadRow = null;
                return;
            }

            let item = _uploadFileList[0];
            _uploadFileList.splice(0, 1);//取出第一项后,将第一项从待上传列表中移除
            let rowId = item.id.toString();
            _uploadRow = document.getElementById(rowId);
            if (_uploadRow != null && _uploadRow != undefined) {
                _uploadRow.children[3].children[0].setAttribute("disabled", "disabled");
            }

            // 创建一个空的formData表单对象，页面中没有form标签，所以这里创建一个空的表单对象
            let formData = new FormData();
            formData.append(item.name, item.file);
            let url = baseUrl + "uploadFile?path=" + _path;
            $.ajax({
                type: "POST",
                url: url,
                data: formData,
                async: true,
                contentType: false,//值只能填写false，不能用form的值"multipart/form-data",否则jquery内部会作些处理，就会缺少字段
                processData: false,
                xhr: function () {
                    let xhr = new XMLHttpRequest();
                    //使用XMLHttpRequest.upload监听上传过程，注册progress事件，打印回调函数中的event事件
                    xhr.upload.addEventListener('progress', function (e) {
                        //console.log(e);//progress { target: XMLHttpRequestUpload, isTrusted: true, lengthComputable: true, loaded: 761134475, total: 770732404, srcElement: XMLHttpRequestUpload, currentTarget: XMLHttpRequestUpload, eventPhase: 2, bubbles: false, cancelable: false, … }
                        //loaded代表上传了多少
                        //total代表总数为多少

                        //let progressRate = (e.loaded / e.total) * 100 + '%';
                        //通过设置进度条的宽度达到效果
                        //$('.progress > div').css('width', progressRate);

                        if (_uploadRow != null && _uploadRow != undefined) {
                            let numb = e.loaded / e.total * 100;
                            _uploadRow.children[2].innerText = numb.toFixed(2) + "%";
                            //uploadProBar.innerText = numb.toFixed(2) + "%";
                        }
                    })

                    return xhr;
                },
                success: function (ret, status, p1) {
                    if (ret.status == apiConstants.API_STATUS_SUCCES) {
                        if (_uploadRow != null && _uploadRow != undefined) {
                            //let id = parseInt(_uploadRow.id);
                            //let removeIndex = -1;
                            //for (let i = 0; i < _uploadFileList.length; i++) {
                            //    if (_uploadFileList[i].id == id) {
                            //        removeIndex = i;
                            //        break;
                            //    }
                            //}
                            //if (removeIndex >= 0) {
                            //    _uploadFileList.splice(removeIndex, 1);
                            //}
                            _uploadRow.remove();
                        }
                        _uploadRow = null;

                        refreshList(_path);
                        primitiveUploadFile();
                    }
                    else {
                        if (_uploadRow != null && _uploadRow != undefined) {
                            _uploadRow.children[2].innerText = "失败";
                        }

                        showErr(ret.data);
                    }
                },
                error: function (err, p1) {
                    if (_uploadRow != null && _uploadRow != undefined) {
                        _uploadRow.children[2].innerText = "失败";
                    }
                    showErrRet(err, p1);
                }
            });
        }

        function onCancelUpload(id) {
            let rowId = id.toString();
            let rowEle = document.getElementById(rowId);
            if (rowEle != null && rowEle != undefined) {
                rowEle.remove();
            }
        }

        function eleChanged(sender) {
            let rowEle = null;
            let ts = getTimestamp();
            let index = 0;
            for (let file of sender.files) {
                let item = {};
                item.id = ts + index++;
                item.name = file.name;
                item.file = file;
                _uploadFileList.push(item);

                rowEle = tbUploadEle.insertRow(tbUploadEle.children.length);
                rowEle.id = item.id;
                rowEle.innerHTML = '<td>' + item.name + '</td ><td>' + file.size / 1024 + '</td><td>0</td><td><button onclick="onCancelUpload(' + item.id + ')">取消</button>';
                //rowEle.children[0].innerText = item.name;
                //rowEle.children[1].innerText = file.size / 1024;
                //rowEle.children[2].innerText = "0";
                //rowEle.children[3].innerText = '<button onclick="onCancelUpload(' + item.id + ')">取消</button>';
            }

            if (!_uploading) {
                _uploading = true;
                primitiveUploadFile();
            }
        }

        function onUploadFile() {
            let ele = document.getElementById("txtUploadFile");
            ele.value = "";//清空前一次选择的文件
            ele.click();
        }

        function onCreateDir() {
            let dir = $("#newDir").val().trim();
            if (dir == "") {
                showErr("目录不能为空");
                return;
            }

            let url = baseUrl + "createDirectory?path=" + _path + '/' + dir;
            $.ajax({
                type: "GET",
                url: url,
                async: true,
                contentType: "application/json; charset=utf-8",
                //dataType: "json",
                success: function (ret, status, p1) {
                    if (ret.status == apiConstants.API_STATUS_SUCCES) {
                        refreshList(_path);
                    }
                    else {
                        showErr(ret.data);
                    }
                },
                error: showErrRet
            });
        }

        function onBatchDelete() {
            let arr = new Array();
            let trEles = tbList.children[1].children;
            for (let trEle of trEles) {
                if (trEle.children[0].children[0].checked == true) {
                    let item = {};
                    item.name = trEle.children[1].children[0].innerHTML;
                    if (trEle.getAttribute("data-type") == "1") {//文件
                        item.length = 1;
                    }
                    else {//目录
                        item.length = 0;
                    }
                    arr.push(item);
                }
            }

            if (arr.length == 0) {
                return;
            }

            let data = {};
            data.list = arr;
            data.path = decodeURIComponent(_path);
            let url = baseUrl + "delete";
            let json = JSON.stringify(data);

            $.ajax({
                type: "POST",
                url: url,
                data: json,
                async: true,
                contentType: "application/json; charset=utf-8",
                //dataType: "json",
                success: function (ret, status, p1) {
                    if (ret.status == apiConstants.API_STATUS_SUCCES) {
                        refreshList(_path);
                    }
                    else {
                        showErr(ret.data);
                    }
                },
                error: showErrRet
            });
        }


        function switchDir(dir) {
            _path = _path + '/' + dir;
            refreshList(_path);
        }

        function chioceDir(ele) {
            _path = ele.getAttribute("data-path");
            refreshList(_path);
        }

        function onBatchDownload() {
            let trEles = tbList.children[1].children;
            for (let trEle of trEles) {
                if (trEle.children[0].children[0].checked == true) {
                    if (trEle.getAttribute("data-type") == "0") {
                        //目录
                        continue;
                    }

                    //文件
                    trEle.children[1].children[0].click();
                }
            }
        }

        function filter() {
            filterText = document.getElementById("txtFilter").value.trim().toLowerCase();
            showList();
        }

        function txtSearchKeyKeydown(e) {
            if (e.key === "Enter") {
                deepSearch();
            }
        }

        function onLoad() {
            tbListEle = document.getElementById("tbList");
            tbUploadEle = document.getElementById("tbUpload");
            uploadProBar = document.getElementById('bar');

            document.getElementById("txtFilter").addEventListener('input', filter);
            document.getElementById("txtSearchKey").addEventListener('keydown', txtSearchKeyKeydown);

            refreshList(_path);
        }

    </script>
</head>
<body onload="onLoad()">
    <div style="height: 30px; border: solid 1px gray; margin: 5px" id="divNav">
        <!--<span>..</span>/<span>aa</span>/<span>bb</span>/<span>c</span>-->
    </div>

    <div style="border: solid 1px gray; margin: 5px; height: calc(100vh - 100px); overflow-y: auto; width: 70%; float: left">
        <div style="height: 30px; margin: 5px; border-bottom: solid 1px gray;">
            <span style="color:black">筛选：</span>
            <input type="text" id="txtFilter" value="" style="margin-left:5px;width:200px"  placeholder="筛选关键字"/>

            <input type="text" id="txtSearchKey" value="" style="margin-left:50px;width:200px" placeholder="搜索关键字"/>
            <input type="button" value="深度搜索" onclick="deepSearch()"/>
        </div>

        <table id="tbList">
            <thead>
                <tr>
                    <td style="width:50px">选中</td>
                    <td style="width:400px">名称</td>
                    <td style="width:200px">创建时间</td>
                    <td style="width:200px">最后修改时间</td>
                    <td style="width:200px">文件长度</td>
                </tr>
            </thead>

            <tr>
                <td><input type="checkbox" /></td>
                <td>
                    <label onclick=""></label>
                    <a href=""></a>
                </td>
                <td>创建时间</td>
                <td>最后修改时间</td>
                <td>文件长度</td>
            </tr>
        </table>
    </div>

    <div style="border: solid 1px gray; height: calc(100vh - 100px); overflow-y: auto; margin: 10px 0px 0px 0px; width: calc(30% - 20px) ">
        <table id="tbUpload">
            <thead>
                <tr>
                    <td style="width:400px">名称</td>
                    <td style="width:200px">大小K</td>
                    <td style="width:200px">进度%</td>
                    <td style="width:200px">操作</td>
                </tr>
            </thead>

            <!--<tr id="qwe">
                <td>
                    feiq.exe
                </td>
                <td>205</td>
                <td>0</td>
                <td><button onclick="onCreateDir(123)">取消</button></td>
            </tr>-->
        </table>
    </div>

    <div style="height: 40px; border: solid 1px gray; margin: 5px">
        <style type="text/css">
            button {
                margin: 2px;
                vertical-align: central;
                width: 110px;
                height: 35px;
            }
        </style>

        <button onclick="checkAll()" style="margin-left:10px">全选</button>
        <button onclick="unCheckAll()" style="margin-left:10px">全不选</button>
        <button onclick="unCheck()" style="margin-left:10px">反选</button>

        <button onclick="onRefresh()" style="margin-left:10px">刷新</button>
        <input title="文件" id="txtUploadFile" accept="*.*" type="file" multiple="multiple" style="display:none" onchange="eleChanged(this)">
        <button onclick="onUploadFile()" style="margin-left:10px">上传</button>
        <button onclick="onBatchDelete()" style="margin-left:10px">删除</button>
        <button onclick="onBatchDownload()" style="margin-left:10px">下载</button>
        <label style="margin-left:10px">目录名</label>
        <input type="text" id="newDir" value="" style="height:30px" />
        <button onclick="onCreateDir()">创建目录</button>
    </div>

</body>
</html>